package com.unitedvision.persistence.domain;

import java.util.List;

import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Entity;

import com.unitedvision.core.domain.Inventory;
import com.unitedvision.core.exception.WrongFormatException;

@Entity
@Table (name = "inventory")
public class InventoryEntity {
	private int id;
	private CompanyEntity company;
	private GoodsEntity goods;
	private int numberOfGoods;
	private long price;
	private List<TransactionEntity> transactions;
	
	public InventoryEntity() {
		super();
	}

	public InventoryEntity(Inventory inventory) throws WrongFormatException {
		super();
		this.id = inventory.getId();
		this.company = CompanyEntity.create(inventory.getCompany());
		this.goods = GoodsEntity.create(inventory.getGoods());
		this.numberOfGoods = inventory.getNumberOfGoods();
		this.price = inventory.getPrice();
	}

	public InventoryEntity(CompanyEntity company, GoodsEntity goods, int numberOfGoods, long price) {
		super();
		this.company = company;
		this.goods = goods;
		this.numberOfGoods = numberOfGoods;
		this.price = price;
	}

	@Id @GeneratedValue
	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	@ManyToOne (fetch = FetchType.EAGER)
	@JoinColumn (name = "company_id", referencedColumnName = "id")
	public CompanyEntity getCompany() {
		return company;
	}

	public void setCompany(CompanyEntity company) {
		this.company = company;
	}

	@ManyToOne (fetch = FetchType.EAGER)
	@JoinColumn (name = "goods_id", referencedColumnName = "id")
	public GoodsEntity getGoods() {
		return goods;
	}

	public void setGoods(GoodsEntity goods) {
		this.goods = goods;
	}

	@Column (name = "number_of_goods")
	public int getNumberOfGoods() {
		return numberOfGoods;
	}

	public void setNumberOfGoods(int numberOfGoods) {
		this.numberOfGoods = numberOfGoods;
	}

	@Column (name = "price")
	public long getPrice() {
		return price;
	}

	public void setPrice(long price) {
		this.price = price;
	}
	
	@OneToMany (targetEntity = TransactionEntity.class, mappedBy = "inventory", fetch = FetchType.LAZY)
	public List<TransactionEntity> getTransactions() {
		return transactions;
	}

	public void setTransactions(List<TransactionEntity> transactions) {
		this.transactions = transactions;
	}

	public Inventory toInventory() {
		return new Inventory(id, company.toCompany(), goods.toGoods(), numberOfGoods, price);
	}
	
	public static InventoryEntity create(CompanyEntity company, GoodsEntity goods, int numberOfGoods, long price) {
		return new InventoryEntity(company, goods, numberOfGoods, price);
	}

	public static InventoryEntity create(Inventory inventory) throws WrongFormatException {
		return new InventoryEntity(inventory);
	}

	@Override
	public String toString() {
		return "InventoryEntity [id=" + id + ", company=" + company
				+ ", goods=" + goods + ", numberOfGoods=" + numberOfGoods
				+ ", price=" + price + "]";
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((company == null) ? 0 : company.hashCode());
		result = prime * result + ((goods == null) ? 0 : goods.hashCode());
		result = prime * result + id;
		result = prime * result + numberOfGoods;
		result = prime * result + (int) (price ^ (price >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		InventoryEntity other = (InventoryEntity) obj;
		if (company == null) {
			if (other.company != null)
				return false;
		} else if (!company.equals(other.company))
			return false;
		if (goods == null) {
			if (other.goods != null)
				return false;
		} else if (!goods.equals(other.goods))
			return false;
		if (id != other.id)
			return false;
		if (numberOfGoods != other.numberOfGoods)
			return false;
		if (price != other.price)
			return false;
		return true;
	}
}
